<?php

/*
 * Copyright 2008 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#namespace tehframework\annotations\parsers;

#use \stdClass;
#use \ReflectionException;
#use \ReflectionClass;
#use tehframework\testing\phpunit\TestCase;

require_once 'test/testHelper.php';

class ConstantValueParserImplTest extends TestCase
{
	const TEST_CONSTANT = 1;
	
	/**
	 * @var ConstantValueParserImpl
	 */
	private $parser;
	
	protected function setUp()
	{
		$this->parser = new ConstantValueParserImpl();
	}
	
	function testParseConstantValueConvertsQuotedStringToString()
	{
		$tests = array
		(
			'""'         => '',
			'"test"'     => 'test',
			'"\'"'       => "'",
			'"\\\"'       => '\\',
			'"esc\"ape"' => 'esc"ape'
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value . '.');
		}
	}
	
	function testParseConstantValueConvertsIntStringToInt()
	{
		$tests = array
		(
			'1'      => 1,
			'-1'     => -1,
			'0'      => 0,
			'123456' => 123456
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value . '.');
		}
	}
	
	function testParseConstantValueConvertsFloatStringToFloat()
	{
		$tests = array
		(
			'1.0'        => 1.0,
			'-1.23'      => -1.23,
			'123456.789' => 123456.789
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value . '.');
		}
	}
	
	function testParseConstantValueConvertsHexadecimalStringToNumber()
	{
		$tests = array
		(
			'0x1'  => 1,
			'0x0'  => 0,
			'0xFF' => 255,
			'0x1a' => 26
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value . '.');
		}
	}
	
	function testParseConstantValueConvertsOctalStringToNumber()
	{
		$tests = array
		(
			'02'   => 2,
			'010'  => 8,
			'0123' => 83
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value);
		}
	}
	
	function testParseConstantValueConvertsPredefinedStringToItsValue()
	{
		$tests = array
		(
			'true'   => true,
			'TrUe'   => true,
			'yes'    => true,
			'ON'     => true,
			'false'  => false,
			'NO'     => false,
			'off'    => false,
			'null'   => null
		);
		
		foreach ($tests as $value => $expected)
		{
			$this->assertSame($expected, $this->parser->parseConstantValue($value),
				'Failed on: ' . $value);
		}
	}
	
	function testParseConstantValueReturnsReflectionClassForStringsEndingWithDotClass()
	{
		$reflection = $this->parser->parseConstantValue('stdClass.class');
		
		$this->assertType('ReflectionClass', $reflection);
		$this->assertSame('stdClass', $reflection->getName());
	}
	
	function testParseConstantValueThrowsReflectionExceptionIfSpecifiedClassDoesNotExist()
	{
		$this->setExpectedException('ParserException');
		
		$this->parser->parseConstantValue('HopefullyIDoNotExist.class');
	}
	
	function testParseConstantValueReturnsValueOfExistingPHPConstant()
	{
		$this->assertSame(
			self::TEST_CONSTANT,
			$this->parser->parseConstantValue(
				'ConstantValueParserImplTest::TEST_CONSTANT')
		);
	}
	
	function testParseConstantValueThrowsReflectionExceptionIfConstantDoesNotExist()
	{
		$this->setExpectedException('ParserException');
		
		$this->parser->parseConstantValue('HOPEFULLY_I_DO_NOT_EXIST');
	}
}